home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / system / abort.zip / ABORT.A86 next >
Text File  |  1986-03-23  |  6KB  |  244 lines

  1. ; ABORT.EXE    (updated 02/19/86 by S. Kluger to document change
  2. ; required to reassign the abort key (ALT-C by default)).
  3. ; The problem is that ^C when used in WordStar sometimes will
  4. ; abort to DOS...  Use the tech manual to find a new key value
  5. ; and stuff it in where marked with [SFK]...
  6. ;
  7. ; a program to trap the Control-C key and to abort
  8. ; the currently resident process (such as the DSI Loader)
  9. ; derived from :
  10. ; buf128:  a 128 character type-ahead buffer for the IBM-PC
  11. ; by Trevor Marshall 10/12/85
  12. ;
  13. ; This program is assembled with DRI's RASMPC.EXE (or with RASM86.CMD under
  14. ; CCP/M) and linked with LINK.EXE or LINKPC.EXE.
  15. ;
  16. ; This program works by intercepting the calls to the BIOS
  17. ; interrupt routines at 9 for the keystroke interrupts and
  18. ; 16H for the program requests
  19. ; Everything is kept in the CS.
  20. ;
  21. ; NOTE that you should abort a program only if you know exactly what you're
  22. ;      doing (ie a runaway program just infinite-looped etc). Any open files
  23. ;      will NOT be closed and you should run CHKDSK /F immediately to clean
  24. ;      up the file system!
  25. ;
  26.         cseg 
  27.         public    main_,key_int,request,buffer,head,tail
  28. ;
  29. KEYINT        equ    .24H        ; int 9 vector offset
  30. REQINT        equ    .58H        ; int 16H vector offset
  31. B_HEAD        equ    .1AH        ; offset to BUFFER_HEAD
  32. B_TAIL        equ    .1CH        ; offset to BUFFER_TAIL
  33. KB_FLAG        equ    .17H        ; offset to KB_FLAG
  34.  
  35. main_:        jmp    init_code
  36. ;
  37. buffer        dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  38.         dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  39.         dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  40.         dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  41.         dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  42.         dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  43.         dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  44.         dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  45.  
  46. head        dw    buffer
  47. tail        dw    buffer
  48. ax_save        dw    0
  49. bx_save        dw    0
  50. code_seg    dw    0
  51. ;
  52. ; the keystroke interrupt routine.  Interrcept the key interrupt, run
  53. ; it through the standard key input routine, and remove it from the buffer.
  54. ;
  55.  
  56. key_int:
  57.         cli
  58. ;Find out where we are coming from
  59.         mov    WORD PTR ax_save,ax ;save AX a while
  60.         mov    WORD PTR bx_save,bx ;save BX a while
  61.         pop    ax    ;reurn address into AX
  62.         pop    bx    ;now have calling code segment in BX
  63.         push    bx    ;restore the stack
  64.         push    ax
  65.         mov    WORD PTR code_seg,bx ;save it for later
  66.         mov    ax,WORD PTR ax_save ;restore AX
  67.         mov    bx,WORD PTR bx_save ;restore BX
  68. ;begin the handler
  69.         pushf            ; simulate an interrupt on return
  70.  
  71. ;
  72. ; long call to F000:E987
  73. ; (this poses a problem with non-compatible BIOSes such as the one
  74. ; found in the latest Leading Edge model M, but should work in
  75. ; most clones.    [sfk]
  76. ;
  77.         db    9AH
  78.         dw    0E987H
  79.         dw    0F000H
  80. ;
  81.         push    bx
  82.         push    es
  83.         push    ax
  84.         mov    bx,40H        ; BIOS data segment
  85.         mov    es,bx
  86.         mov    bx, es:WORD PTR B_HEAD    ; pointer to datum
  87.         cmp    bx, es:WORD PTR B_TAIL    ; test for character
  88.         je    k_esbx            ;return if none
  89.         mov    es:WORD PTR B_TAIL, bx    ; clear the buffer
  90.         mov    bx, es:[bx]    ;get the char to bx
  91. ;
  92.     mov    ax,bx    ;get char to ax
  93. ;
  94. ; [SFK]
  95. ; the following line for use with "normal" key codes:
  96. ; replace the "3" with whatever key scan code you wish to
  97. ; use as the ABORT key (CTRL-D = 4 etc).
  98. ;    cmp    al,3    ;ready to see if its a control-c
  99. ;
  100. ; [SFK]
  101. ; comment out the cmp above and enable the following line if an EXTENDED
  102. ; key is to be the ABORT key, such as ALT-X, CTRL-F10, or whatever.
  103. ; Note: the scan code must be in hex, and must be contained in the
  104. ; upper byte of the compare word as shown in the example. The low
  105. ; byte must be 00!
  106.     cmp    ax,2E00H    ; test for abort key (ALT-C)
  107. ;
  108.     jne    no_abort ;if not then continue
  109. ;Before aborting we must check that DOS  itself is not the current process.
  110. ; We can do this by checking that the calling code segment is higher than
  111. ; the segment at which this driver was loaded
  112.     mov    ax,WORD PTR code_seg
  113.     db    3dh    ;CMP AX,
  114. POKE1    dw    0    ;overwritten by initializer code
  115.     jb    no_abort ;if current CS is below us then dont abort
  116. ;Also check that we are not executing the BIOS ROM
  117.     cmp    ax,0af00h
  118.     jnb    no_abort
  119.     pop    ax
  120.     pop    es
  121.     pop    bx
  122. ;issue a non-specific EOI to the 8259
  123.     mov    al,20h
  124.     out    20h,al
  125. ;issue a specific EOI to the floppies
  126. ;    mov    al,26h
  127. ;    out    20h,al
  128. ;issue a specific EOI to the fixed disk
  129. ;    mov    al,25h
  130. ;    out    20h,al
  131. ;
  132.     mov    ah,4ch
  133.     mov    al,0    ;no errors to report
  134.     sti        ;all ok again for interrupts now
  135.     int    21h
  136. no_abort:
  137. ;
  138.         push    si
  139.         mov    si, cs:tail
  140.         push    si        ; save tail value
  141.         add    si,2        ; test for full
  142.         cmp    si, offset buffer+256
  143.         jb    k_over1
  144.         mov    si, offset buffer
  145. k_over1:
  146.         cmp    si, cs:head
  147.         pop    si
  148.         je    k_siesbx    ; jump if buffer full
  149.         mov    cs:[si], bx    ; store the character
  150.         add    si,2
  151.         cmp    si, offset buffer+256
  152.         jb    k_over2
  153.         mov    si, offset buffer    ;wrap around
  154. k_over2:
  155.         mov    cs:tail, si
  156. k_siesbx:
  157.         pop    si
  158. k_esbx:
  159.         pop    ax
  160.         pop    es        ; no character, return
  161.         pop    bx
  162.         iret
  163.  
  164. ;
  165. ; The request interrupt routine.
  166. ;
  167. ; simulate the BIOS routine
  168. ;    ah = 0    read next char
  169. ;    ah = 1    set Z flag on character status, ZF=1 if no char
  170. ;        ZF=0 and AX = char if char ready
  171. ;    ah = 2    shift status
  172.  
  173.  
  174. request:
  175.         sti
  176.         or    ah,ah
  177.         jz    do_read
  178.         dec    ah
  179.         jz    do_stat
  180.         dec    ah
  181.         jz    do_shift
  182.         iret
  183.  
  184. do_read:                ; return the next character
  185.         sti
  186.         nop
  187.         cli
  188.         mov    ax,cs:head
  189.         cmp    ax,cs:tail
  190.         je    do_read        ; loop until a character
  191.         push    bx
  192.         mov    bx,ax
  193.         mov    ax, cs:[bx]    ; ax gets the character
  194.         add    bx,2
  195.         cmp    bx, offset buffer+256
  196.         jb    r_over
  197.         mov    bx, offset buffer
  198. r_over:
  199.         cmp    bx, cs:tail
  200.         mov    cs:head, bx    ; new head
  201.         pop    bx
  202.         iret
  203.  
  204. do_stat:                ; return key status
  205.         cli
  206.         push    bx
  207.         mov    bx,cs:head
  208.         cmp    bx,cs:tail
  209.         mov    ax,cs:[bx]
  210.         pop    bx
  211.         sti
  212.         retf    2        ; throw out the flags
  213.  
  214. do_shift:
  215.         push    es
  216.         mov    ax,40H        ; BIOS data segment
  217.         mov    es,ax
  218.         mov    al, es:byte ptr KB_FLAG
  219.         pop    es
  220.         iret
  221.         
  222. init_code:    cli            ; turn off interrupts for now
  223.         mov    ax,0
  224.         mov    es,ax        ; segment base for vectors
  225.         mov    es:WORD PTR KEYINT, offset key_int
  226.         mov    es:WORD PTR KEYINT+2, cs
  227.         mov    es:WORD PTR REQINT, offset request
  228.         mov    es:WORD PTR REQINT+2, cs
  229.         mov    cs:head, offset buffer
  230.         mov    cs:tail, offset buffer
  231. ; Code added 10/12/85 by TM to calculate the current CS value and poke it into
  232. ; the location in the interrupt handler which checks that DOS is not the
  233. ; current task
  234.         mov    cs:WORD PTR poke1, cs
  235. ;
  236.         sti
  237.         mov    ds:byte ptr .1, 27H    ; change PCB terminate to resident
  238.         push    ds
  239.         mov    dx,0
  240.         push    dx
  241.         mov    dx, offset init_code+100H
  242.         retf            ; long return to the int 27H
  243.         end
  244.